<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        
        <meta name="author" content="隐星魂 (Roy.Sun)">
        
        <link rel="shortcut icon" href="../../img/favicon.ico">
        <title>构建系统 - 玄武操作系统</title>
        <link href="../../css/bootstrap.min.css" rel="stylesheet">
        <link href="../../css/font-awesome.min.css" rel="stylesheet">
        <link href="../../css/base.css" rel="stylesheet">
        <link rel="stylesheet" href="https://cdn.staticfile.org/highlight.js/10.0.3/styles/color-brewer.min.css">

        <script src="../../js/jquery-1.10.2.min.js" defer></script>
        <script src="../../js/bootstrap.min.js" defer></script>
        <script src="https://cdn.staticfile.org/highlight.js/10.0.3/highlight.min.js"></script>
        <script>hljs.initHighlightingOnLoad();</script> 
    </head>

    <body>
        <div class="navbar fixed-top navbar-expand-lg navbar-dark bg-primary">
            <div class="container">
                <a class="navbar-brand" href="../..">玄武操作系统</a>
                <!-- Expander button -->
                <button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar-collapse">
                    <span class="navbar-toggler-icon"></span>
                </button>

                <!-- Expanded navigation -->
                <div id="navbar-collapse" class="navbar-collapse collapse">
                        <!-- Main navigation -->
                        <ul class="nav navbar-nav">
                            <li class="navitem">
                                <a href="../.." class="nav-link">介绍</a>
                            </li>
                            <li class="navitem">
                                <a href="../../license/" class="nav-link">开源协议</a>
                            </li>
                            <li class="dropdown active">
                                <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">应用手册 <b class="caret"></b></a>
                                <ul class="dropdown-menu">
                                    
<li>
    <a href="../01.%E7%AE%80%E4%BB%8B/" class="dropdown-item">简介</a>
</li>
                                    
<li>
    <a href="../02.%E7%B3%BB%E7%BB%9F%E5%9F%BA%E6%9C%AC%E6%9E%B6%E6%9E%84/" class="dropdown-item">系统基本架构</a>
</li>
                                    
<li>
    <a href="./" class="dropdown-item active">构建系统</a>
</li>
                                    
<li>
    <a href="../04.%E5%90%AF%E5%8A%A8%E6%B5%81%E7%A8%8B/" class="dropdown-item">启动流程</a>
</li>
                                    
<li>
    <a href="../05.%E5%9F%BA%E6%9C%AC%E7%BA%A6%E5%AE%9A/" class="dropdown-item">基本约定</a>
</li>
                                    
<li>
    <a href="../06.%E4%B8%AD%E6%96%AD%E6%8E%A7%E5%88%B6/" class="dropdown-item">中断控制</a>
</li>
                                    
<li>
    <a href="../07.%E8%B0%83%E5%BA%A6%E5%99%A8/" class="dropdown-item">调度器</a>
</li>
                                    
<li>
    <a href="../08.%E7%BA%BF%E7%A8%8B/" class="dropdown-item">线程</a>
</li>
                                    
<li>
    <a href="../09.%E7%94%B5%E6%BA%90%E7%AE%A1%E7%90%86/" class="dropdown-item">电源管理</a>
</li>
                                    
<li>
    <a href="../10.%E8%BD%AF%E4%BB%B6%E5%AE%9A%E6%97%B6%E5%99%A8/" class="dropdown-item">软件定时器</a>
</li>
                                    
<li>
    <a href="../11.%E9%94%81/" class="dropdown-item">锁</a>
</li>
                                    
<li>
    <a href="../12.%E5%90%8C%E6%AD%A5/" class="dropdown-item">同步</a>
</li>
                                    
<li>
    <a href="../13.%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86/" class="dropdown-item">内存管理</a>
</li>
                                    
<li>
    <a href="../14.%E7%8E%84%E6%AD%A6C%E5%BA%93/" class="dropdown-item">玄武C库</a>
</li>
                                </ul>
                            </li>
                            <li class="dropdown">
                                <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">快速开发指南 <b class="caret"></b></a>
                                <ul class="dropdown-menu">
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">S32k</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../%E5%BF%AB%E9%80%9F%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97/s32k/1.XuanWuOS-envsetup-guide/" class="dropdown-item">开发环境搭建指南</a>
</li>
            
<li>
    <a href="../../%E5%BF%AB%E9%80%9F%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97/s32k/2.XuanWuOS-project-setup-guide/" class="dropdown-item">工程配置指南</a>
</li>
    </ul>
  </li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">Stm32</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../%E5%BF%AB%E9%80%9F%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97/stm32/1.XuanWuOS-envsetup-guide/" class="dropdown-item">开发环境搭建指南</a>
</li>
            
<li>
    <a href="../../%E5%BF%AB%E9%80%9F%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97/stm32/2.XuanWuOS-project-setup-guide/" class="dropdown-item">工程配置指南</a>
</li>
            
<li>
    <a href="../../%E5%BF%AB%E9%80%9F%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97/stm32/3.XuanWuOS-xwbd-atkh743/" class="dropdown-item">正点原子阿波罗H743开发板上手指南</a>
</li>
            
<li>
    <a href="../../%E5%BF%AB%E9%80%9F%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97/stm32/4.XuanWuOS-xwbd-fk429m/" class="dropdown-item">反客F429核心板上手指南</a>
</li>
            
<li>
    <a href="../../%E5%BF%AB%E9%80%9F%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97/stm32/5.XuanWuOS-xwbd-atkf407core/" class="dropdown-item">正点原子F407核心板上手指南</a>
</li>
            
<li>
    <a href="../../%E5%BF%AB%E9%80%9F%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97/stm32/6.XuanWuOS-xwbd-atkf103core/" class="dropdown-item">正点原子F103核心板上手指南</a>
</li>
    </ul>
  </li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">Xwko</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../%E5%BF%AB%E9%80%9F%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97/xwko/1.XuanWuKO-guide/" class="dropdown-item">玄武内核模块快速上手指南</a>
</li>
    </ul>
  </li>
                                </ul>
                            </li>
                            <li class="dropdown">
                                <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">规范 <b class="caret"></b></a>
                                <ul class="dropdown-menu">
                                    
<li>
    <a href="../../%E8%A7%84%E8%8C%83/git-commit-specification/" class="dropdown-item">git commit规范</a>
</li>
                                    
<li>
    <a href="../../%E8%A7%84%E8%8C%83/version-branch-specification/" class="dropdown-item">分支与版本号</a>
</li>
                                </ul>
                            </li>
                        </ul>

                    <ul class="nav navbar-nav ml-auto">
                        <li class="nav-item">
                            <a href="#" class="nav-link" data-toggle="modal" data-target="#mkdocs_search_modal">
                                <i class="fa fa-search"></i> 搜索
                            </a>
                        </li>
                            <li class="nav-item">
                                <a rel="prev" href="../02.%E7%B3%BB%E7%BB%9F%E5%9F%BA%E6%9C%AC%E6%9E%B6%E6%9E%84/" class="nav-link">
                                    <i class="fa fa-arrow-left"></i> 上一篇
                                </a>
                            </li>
                            <li class="nav-item">
                                <a rel="next" href="../04.%E5%90%AF%E5%8A%A8%E6%B5%81%E7%A8%8B/" class="nav-link">
                                    下一篇 <i class="fa fa-arrow-right"></i>
                                </a>
                            </li>
                    </ul>
                </div>
            </div>
        </div>

        <div class="container">
            <div class="row">
                    <div class="col-md-3"><div class="navbar-light navbar-expand-md bs-sidebar hidden-print affix" role="complementary">
    <div class="navbar-header">
        <button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#toc-collapse" title="Table of Contents">
            <span class="fa fa-angle-down"></span>
        </button>
    </div>

    
    <div id="toc-collapse" class="navbar-collapse collapse card bg-secondary">
        <ul class="nav flex-column">
            
            <li class="nav-item" data-level="1"><a href="#_1" class="nav-link">构建系统</a>
              <ul class="nav flex-column">
            <li class="nav-item" data-level="2"><a href="#_2" class="nav-link">构建流程</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#_10" class="nav-link">编译选项</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#_11" class="nav-link">玄武模块</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#_15" class="nav-link">辅助功能</a>
              <ul class="nav flex-column">
              </ul>
            </li>
              </ul>
            </li>
        </ul>
    </div>
</div></div>
                    <div class="col-md-9" role="main">

<h1 id="_1">构建系统</h1>
<h2 id="_2">构建流程</h2>
<p>玄武OS的构建是从<strong>xwbd/电路板名称/</strong>目录下执行命令<strong>make</strong>开始的，
以<strong>$XWOS_BRD_DIR</strong>代表此目录。生成的文件全部位于<strong>$XWOS_BRD_DIR/wkspc</strong>中。</p>
<p><img alt="img" src="../res/figure/build-flow.png" title="玄武OS构建流程" /></p>
<h3 id="_3">生成配置</h3>
<ul>
<li>构建系统会调用脚本<strong>xwbs/util/el/mkcfg.el</strong>处理<strong>$XWOS_BRD_DIR/cfg</strong>下的
    所有配置文件，将它们转化成<strong>$XWOS_BRD_DIR/wkspc/XuanWuOS.cfg</strong>，
    这个配置文件之后会被构建系统引入。</li>
</ul>
<pre><code class="makefile">## ******** ******** ******** basic info ******** ******** ******** ##
XuanWuOS_CFG_HOSTOS := gnu/linux # 编译主机的操作系统
XuanWuOS_CFG_ARCH := arm # 架构
XuanWuOS_CFG_SUBARCH := v7m # 子架构
XuanWuOS_CFG_COMPILER := gcc # 编译器
XuanWuOS_CFG_LDSCRIPT := cfg/XuanWuOS.lds # 连接脚本在$(XuanWuOS_CFG_BRD)中的路径
XuanWuOS_CFG_CPU := m4 # CPU子集名称
XuanWuOS_CFG_SOC := stm32f4x # SOC芯片名称
XuanWuOS_CFG_PERPHERAL := y # 是否启用外设库
XuanWuOS_CFG_BRD := fk429m # 电路板名称
XuanWuOS_CFG_CORE := smp # 内核是SMP还是UP
XuanWuOS_CFG_XWMD := y # 是否启用中间件
XuanWuOS_CFG_XWEM := y # 是否启用第三方模块
XuanWuOS_CFG_XWAM := y # 是否启用应用模块
XuanWuOS_CFG_MK_RULE := arm-cortex-m.gcc.rule # 选择xwbs目录下的编译规则文件
XuanWuOS_CFG_ELF_MK := arm-cortex-m.gcc.mk # 编译ELF的makefile文件
XuanWuOS_CFG_XWMO_MK := arm-cortex-m.gcc.xwmo.mk # 编译模块的makefile文件
## ******** ******** ******** ******** build Script info ******** ******** ******** ******** ##
XWBS_UTIL_MK_XWMO := xwbs/util/mk/xwmo.mk # 定义了编译玄武模块的一些辅助功能
## ******** ******** ******** directory info ******** ******** ******** ##
XWOS_PATH := /path/to/XuanWuOS # 玄武OS源代码的绝对路径
XWOS_KN_DIR := xwos # 内核文件夹
XWOS_MD_DIR := xwmd # 中间件文件夹
XWOS_EM_DIR := xwem # 第三方软件包模块文件夹
XWOS_AM_DIR := xwam # 应用模块文件夹
XWOS_ARCH_DIR := xwcd/soc/arm/v7m/gcc # 架构相关代码的路径
XWOS_CPU_DIR := xwcd/soc/arm/v7m/gcc/m4 # CPU相关代码的路径
XWOS_SOC_DIR := xwcd/soc/arm/v7m/gcc/m4/stm32f4x # SOC芯片相关代码的路径
XWOS_PP_DIR := xwcd/perpheral # 外设库文件夹
XWOS_BRD_DIR := xwbd/fk429m # 电路板目录
XWOS_BDL_DIR := xwbd/fk429m/bdl # 电路板相关代码的路径
XWOS_BM_DIR := xwbd/fk429m/bm # 电路板软件包模块文件夹
XWOS_OEM_DIR := xwbd/s32k144evb/oem # OEM模块文件夹
XWOS_WKSPC_DIR := xwbd/fk429m/wkspc # 生成文件的输出文件夹
</code></pre>

<ul>
<li>
<p>脚本<strong>xwbs/util/el/mkcfg.el</strong>会生成<strong>$XWOS_BRD_DIR/wkspc/autogen.h</strong>，
    此文件会被自动包含在顶级头文件<strong>xwos/standard.h</strong>中。</p>
</li>
<li>
<p>脚本<strong>xwbs/util/el/mkcfg.el</strong>最后会生成<strong>$XWOS_BRD_DIR/wkspc/env.rc</strong>，
    在<strong>bash</strong>中<strong>source</strong>这个文件，可在终端环境中引入一些<a href="#orgd8d3662">辅助功能</a>。</p>
</li>
</ul>
<h3 id="adl">编译ADL</h3>
<p>编译系统会根据编译规则<strong>$XWOS_ARCH_DIR/arch.mk</strong>，
编译架构描述层(Arch Description Layer)的源码，
并输出静态库<strong>arch.a</strong>到<strong>$XWOS_WKSPC_DIR/obj</strong>目录下。</p>
<h3 id="cdl">编译CDL</h3>
<p>编译系统会根据编译规则<strong>$XWOS_CPU_DIR/arch.mk</strong>，
编译架构描述层(CPU Description Layer)的源码，
并输出静态库<strong>cpu.a</strong>到<strong>$XWOS_WKSPC_DIR/obj</strong>目录下。</p>
<h3 id="sdl">编译SDL</h3>
<p>编译系统会根据编译规则<strong>$XWOS_SOC_DIR/soc.mk</strong>，
编译架构描述层(SOC Description Layer)的源码，
并输出静态库<strong>soc.a</strong>到<strong>$XWOS_WKSPC_DIR/obj</strong>目录下。</p>
<h3 id="bdl">编译BDL</h3>
<p>编译系统会根据编译规则<strong>$XWOS_BDL_DIR/bdl.mk</strong>，
编译架构描述层(Arch Description Layer)的源码，
并输出静态库<strong>bdl.a</strong>到<strong>$XWOS_WKSPC_DIR/obj</strong>目录下。</p>
<h3 id="xwos">编译XWOS内核</h3>
<p>编译系统会加载位于<strong>xwos/xwos.mk</strong>的编译规则，最后输出静态库
<strong>xwos.a</strong>到<strong>$XWOS_WKSPC_DIR/obj</strong>目录下。</p>
<h3 id="_4">编译中间件</h3>
<ul>
<li>编译系统会扫描<strong>xwmd/</strong>文件夹下的<strong>xwmo.mk</strong>文件，生成模块列表，
    依次将它们编译成<strong>.a</strong>静态库，输出到<strong>$XWOS_WKSPC_DIR/obj</strong>目录下。</li>
<li>每个<strong>xwmo.mk</strong>文件代表了一个模块，其中定义了模块相关的参数：源代码列表、
    附加编译选项、头文件路径等。</li>
<li>每个中间件模块在<strong>$XWOS_BRD_DIR/cfg/xwmd.h</strong>中都有一个编译开关的宏定义，
    编译开关定义为<strong>1</strong>时表示包含这个模块，<strong>0</strong>或<strong>未定义</strong>表示排除这个模块。</li>
<li>编译开关的命名规则参考<a href="#org83708c3">模块编译开关的命名规则</a>。</li>
</ul>
<h3 id="_5">编译外设库</h3>
<ul>
<li>编译系统会扫描<strong>xwcd/perpheral</strong>文件夹下的<strong>xwmo.mk</strong>文件，生成模块列表，
    依次将它们编译成<strong>.a</strong>静态库，输出到<strong>$XWOS_WKSPC_DIR/obj</strong>目录下。</li>
<li>每个<strong>xwmo.mk</strong>文件代表了一个模块，其中定义了模块相关的参数：源代码列表、
    附加编译选项、头文件路径等。</li>
<li>每个外设库模块在<strong>$XWOS_BRD_DIR/cfg/perpheral.h</strong>中都有一个编译开关的宏定义，
    编译开关定义为<strong>1</strong>时表示包含这个模块，<strong>0</strong>或<strong>未定义</strong>表示排除这个模块。</li>
<li>编译开关的命名规则参考<a href="#org83708c3">模块编译开关的命名规则</a>。</li>
</ul>
<h3 id="_6">编译电路板软件模块</h3>
<ul>
<li>编译系统会扫描<strong>$XWOS_BM_DIR</strong>文件夹下的<strong>xwmo.mk</strong>文件，生成模块列表，
    依次将它们编译成<strong>.a</strong>静态库，输出到<strong>$XWOS_WKSPC_DIR/obj</strong>目录下。</li>
<li>每个<strong>xwmo.mk</strong>文件代表了一个模块，其中定义了模块相关的参数：源代码列表、
    附加编译选项、头文件路径等。</li>
<li>每个电路板软件模块在<strong>$XWOS_BRD_DIR/cfg/board.h</strong>中都有一个编译开关的宏定义，
    编译开关定义为<strong>1</strong>时表示包含这个模块，<strong>0</strong>或<strong>未定义</strong>表示排除这个模块。</li>
<li>编译开关的命名规则参考<a href="#org83708c3">模块编译开关的命名规则</a>。</li>
</ul>
<h3 id="_7">编译第三方软件模块</h3>
<ul>
<li>编译系统会扫描<strong>xwem</strong>文件夹下的<strong>xwmo.mk</strong>文件，生成模块列表，
    依次将它们编译成<strong>.a</strong>静态库，输出到<strong>$XWOS_WKSPC_DIR/obj</strong>目录下。</li>
<li>每个<strong>xwmo.mk</strong>文件代表了一个模块，其中定义了模块相关的参数：源代码列表、
    附加编译选项、头文件路径等。</li>
<li>每个外设库模块在<strong>$XWOS_BRD_DIR/cfg/xwem.h</strong>中都有一个编译开关的宏定义，
    编译开关定义为<strong>1</strong>时表示包含这个模块，<strong>0</strong>或<strong>未定义</strong>表示排除这个模块。</li>
<li>编译开关的命名规则参考<a href="#org83708c3">模块编译开关的命名规则</a>。</li>
</ul>
<h3 id="_8">编译应用模块</h3>
<ul>
<li>编译系统会扫描<strong>xwam</strong>文件夹下的<strong>xwmo.mk</strong>文件，生成模块列表，
    依次将它们编译成<strong>.a</strong>静态库，输出到<strong>$XWOS_WKSPC_DIR/obj</strong>目录下。</li>
<li>每个<strong>xwmo.mk</strong>文件代表了一个模块，其中定义了模块相关的参数：源代码列表、
    附加编译选项、头文件路径等。</li>
<li>每个外设库模块在<strong>$XWOS_BRD_DIR/cfg/xwam.h</strong>中都有一个编译开关的宏定义，
    编译开关定义为<strong>1</strong>时表示包含这个模块，<strong>0</strong>或<strong>未定义</strong>表示排除这个模块。</li>
<li>编译开关的命名规则参考<a href="#org83708c3">模块编译开关的命名规则</a>。</li>
</ul>
<h3 id="oem">编译OEM模块</h3>
<ul>
<li>OEM模块文件夹路径由配置XuanWuOS_CFG_OEMPATH指定，此配置位于
    <strong>cfg/XuanWuOS.h</strong>中：<ul>
<li>如果配置为相对路径，则相对于玄武OS的根目录；</li>
<li>可以配置为绝对路径；</li>
<li>路径可以在玄武OS根目录之外。</li>
</ul>
</li>
<li>编译系统会扫描OEM模块文件夹下的<strong>xwmo.mk</strong>文件，生成模块列表，
    依次将它们编译成<strong>.a</strong>静态库，输出到<strong>$XWOS_WKSPC_DIR/obj/oem</strong>目录下。</li>
<li>每个<strong>xwmo.mk</strong>文件代表了一个模块，其中定义了模块相关的参数：源代码列表、
    附加编译选项、头文件路径等。</li>
<li>每个外设库模块在<strong>$XWOS_BRD_DIR/cfg/oem.h</strong>中都有一个编译开关的宏定义，
    编译开关定义为<strong>1</strong>时表示包含这个模块，<strong>0</strong>或<strong>未定义</strong>表示排除这个模块。</li>
<li>编译开关的命名规则参考<a href="#org83708c3">模块编译开关的命名规则</a>。</li>
</ul>
<h3 id="elf">连接ELF文件</h3>
<p>编译系统最终会将以上生成的所有<strong>.a</strong>静态库连接成<strong>XuanWuOS.elf</strong>文件，
连接脚本由<strong>$XWOS_BRD_DIR/$XuanWuOS_CFG_LDSCRIPT</strong>定义。</p>
<h3 id="_9">生成其他文件</h3>
<p>编译系统会将<strong>XuanWuOS.elf</strong>文件转换成<strong>.bin</strong>文件以及<strong>.hex</strong>文件，
也会生成调试脚本等其他文件。</p>
<h2 id="_10">编译选项</h2>
<ul>
<li><strong>~V</strong><ul>
<li>取值：<ul>
<li>1: 开启选项</li>
<li>0: 关闭选项（默认值）</li>
</ul>
</li>
<li>用法：</li>
</ul>
</li>
</ul>
<pre><code class="sh">make ~V=1
</code></pre>

<ul>
<li>
<p>作用：输出完整的编译过程</p>
</li>
<li>
<p><strong>~D</strong></p>
<ul>
<li>取值：<ul>
<li>1: 开启选项（默认值）</li>
<li>0: 关闭选项</li>
</ul>
</li>
<li>用法：</li>
</ul>
</li>
</ul>
<pre><code class="sh">make ~D=0
</code></pre>

<ul>
<li>作用：优化编译，输出体积较小的二进制，但不利于调试。</li>
</ul>
<h2 id="_11">玄武模块</h2>
<p>玄武OS的外设驱动模块、电路板软件模块、中间件模块、第三方软件模块以及OEM模块，
都是使用<strong>xwmo.mk</strong>来描述编译规则的，将它们统一称为<strong>玄武模块</strong>。
<strong>xwmo.mk</strong>的设计原理类似于Android系统中的<strong>Android.mk</strong>。每个<strong>玄武模块</strong>都是
独立编译的，其中定义的编译参数、头文件只对自己有效，这可解决多个第三方软件集成
在一起时的头文件、符号冲突等问题。</p>
<p>示例，<strong>xwbd/fk429m/bm/cxx</strong>的<strong>xwmo.mk</strong>：</p>
<pre><code class="makefile">include $(XWOS_WKSPC_DIR)/XuanWuOS.cfg                 # 包含默认配置
include $(XWBS_UTIL_MK_XWMO)                           # 包含一些Makefile函数

XWMO_CSRCS := init.c                                   # 指定C源文件
XWMO_CFLAGS :=                                         # 指定附加的C编译规则

XWMO_CXXSRCS := task.cxx                               # 指定C++源文件
XWMO_CXXSRCS += operator/allocator.cxx                 # 增加C++源文件
XWMO_CXXSRCS += test/literal.cxx test/vector.cxx       # 增加C++源文件
XWMO_CXXFLAGS := -Wno-unused-value -Wno-literal-suffix # 指定附加的C++编译规则

XWMO_INCDIRS := $(call getXwmoDir)                     # 指定附加的头文件搜索路径
include xwbs/$(XuanWuOS_CFG_XWMO_MK)                   # 引用编译Makefile执行编译
</code></pre>

<h3 id="_12">模块路径命名规则</h3>
<ul>
<li>由于模块路径需要对应于C语言中的一个宏定义作为编译开关，
    因此模块路径需要符合C语言标识符的规则，但可以包含几个特殊符号：<ul>
<li>路径不能以数字开头；</li>
<li>路径中每级目录以"<strong>/</strong>"隔开；</li>
<li>路径中可包含"<strong>.</strong>"，但不能出现"<strong>../</strong>"和"<strong>./</strong>"；</li>
<li>路径中可包含"<strong>-</strong>"；</li>
</ul>
</li>
</ul>
<p><a id="org83708c3"></a></p>
<h3 id="_13">模块编译开关的命名规则</h3>
<ul>
<li>模块路径只需要转换相对路径部分：<ul>
<li>中间件模块：取<strong>xwmd</strong>（不含）之后的路径；</li>
<li>外设驱动模块：取<strong>xwcd/perpheral</strong>（不含）之后的路径；</li>
<li>电路板软件模块：取<strong>$XWOS_BM_DIR</strong>（不含）之后的路径；</li>
<li>第三方软件模块：取<strong>xwem</strong>（不含）之后的路径；</li>
<li>应用模块：取<strong>xwam</strong>（不含）之后的路径；</li>
<li>OEM模块：取<strong>oem目录</strong>（不含）之后的路径。</li>
</ul>
</li>
<li>路径中的"<strong>_</strong>"，需要两个"<strong>_</strong>"来表示；</li>
<li>路径中的"<strong>/</strong>"被转换成<strong>"_</strong>"；</li>
<li>路径中的"<strong>.</strong>"被转换成"<strong>_</strong>"；</li>
<li>路径中的"<strong>-</strong>"被转换成"<strong>_</strong>"；</li>
<li>增加前缀：<ul>
<li>中间件模块：<strong>XWMDCFG</strong></li>
<li>外设驱动模块：<strong>PPCFG</strong></li>
<li>电路板软件模块：<strong>BMCFG</strong></li>
<li>第三方软件模块：<strong>XWEMCFG</strong></li>
<li>应用模块：<strong>XWAMCFG</strong></li>
<li>OEM模块：<strong>OEMCFG</strong></li>
</ul>
</li>
<li>示例：<ul>
<li>中间件模块：<strong>xwmd/isc/xwpcp</strong> &#x2013;&gt; <strong>XWMDCFG_isc_xwpcp</strong> ；</li>
<li>外设驱动模块：<strong>xwcd/perpheral/ds/i2c/eeprom</strong> &#x2013;&gt; <strong>PPCFG_ds_i2c_eeprom</strong> ；</li>
<li>电路板软件模块：<strong>xwbd/fk429m/bm/stm32_cube</strong> &#x2013;&gt; <strong>BMCFG_stm32__cube</strong> ；</li>
<li>第三方软件模块：<strong>xwem/vm/l__u_a-5.4.0</strong> &#x2013;&gt; <strong>XWEMCFG_vm_l____u__a_5_4_0</strong> ；</li>
<li>应用模块：<strong>xwam/example/cxx</strong> &#x2013;&gt; <strong>XWAMCFG_example_cxx</strong> ；</li>
<li>OEM模块：<strong>oem/s32ksdk</strong> &#x2013;&gt; <strong>OEMCFG_s32ksdk</strong> ；</li>
</ul>
</li>
<li>可以借助<a href="#orgd8d3662">辅助功能</a>中的<strong>xwmc</strong>命令生成编译开关的宏标识符。</li>
</ul>
<h3 id="_14">增加模块</h3>
<ol>
<li>中间件模块<ul>
<li>模块位于<strong>xwmd</strong>目录中；</li>
<li>编译开关以<strong>XWMDCFG</strong>为前缀，位于文件<strong>$XWOS_BRD_DIR/cfg/xwmd.h</strong>，
    定义为<strong>1</strong>表示编译模块。</li>
</ul>
</li>
<li>外设驱动模块<ul>
<li>模块位于 <strong>xwcd/perpheral/</strong> 目录中；</li>
<li>编译开关以 <strong>PPCFG</strong> 为前缀，位于文件 <strong>$XWOS_BRD_DIR/cfg/perpheral.h</strong> ，
    定义为<strong>1</strong>表示编译模块。</li>
</ul>
</li>
<li>电路板软件模块<ul>
<li>模块位于<strong>$XWOS_BRD_DIR/bm/</strong>目录中；</li>
<li>编译开关以<strong>BMCFG</strong>为前缀，位于文件<strong>$XWOS_BRD_DIR/cfg/board.h</strong>，
    定义为<strong>1</strong>表示编译模块。</li>
</ul>
</li>
<li>第三方软件模块<ul>
<li>模块位于<strong>xwem/</strong>目录中；</li>
<li>编译开关以<strong>XWEMCFG</strong>为前缀，位于文件<strong>$XWOS_BRD_DIR/cfg/xwem.h</strong>，
    定义为<strong>1</strong>表示编译模块。</li>
</ul>
</li>
<li>应用模块<ul>
<li>模块位于<strong>xwam/</strong>目录中；</li>
<li>编译开关以<strong>XWAMCFG</strong>为前缀，位于文件<strong>$XWOS_BRD_DIR/cfg/xwam.h</strong>，
    定义为<strong>1</strong>表示编译模块。</li>
</ul>
</li>
<li>OEM模块<ul>
<li>模块位于配置<strong>XuanWuOS_CFG_OEMPATH</strong>指定的目录中；</li>
<li>编译开关以<strong>OEMCFG</strong> 为前缀，位于文件<strong>$XWOS_BRD_DIR/cfg/oem.h</strong>，
    定义为<strong>1</strong>表示编译模块。</li>
</ul>
</li>
<li><strong>xwmo.mk</strong>模板</li>
</ol>
<pre><code class="makefile">include $(XWOS_WKSPC_DIR)/XuanWuOS.cfg # 包含配置文件
include $(XWBS_UTIL_MK_XWMO) # 包含一些Makefile函数，例如下面调用的getXwmoDir
XWMO_CSRCS :=             # C源文件
XWMO_CFLAGS :=            # 增加C编译选项
XWMO_CXXSRCS :=           # C++源文件
XWMO_CXXFLAGS :=          # 增加C++编译选项
XWMO_INCDIRS := $(call getXwmoDir)    # 获取模块路径并附加到头文件搜索路径
XWMO_LUASRCS :=           # 增加Lua源文件
include xwbs/$(XuanWuOS_CFG_XWMO_MK)  # 引用编译Makefile执行编译
</code></pre>

<p><a id="orgd8d3662"></a></p>
<h2 id="_15">辅助功能</h2>
<p>为了方便开发，玄武OS定义了一些与模块编译相关的辅助命令。</p>
<h3 id="_16">初始化环境</h3>
<pre><code class="sh">source xwbd/fk429m/env.sh # 假设电路板名称是fk429m
</code></pre>

<h3 id="_17">命令</h3>
<ul>
<li><strong>xwmc</strong><ul>
<li>功能：获取模块编译开关的C语言宏标识符。</li>
<li>用法举例：</li>
</ul>
</li>
</ul>
<pre><code class="sh">cd ${XWOS_PATH}/xwem/vm/lua # 进入到vm/lua模块中
xwmc
&gt; XWEMCFG_vm_lua # 输出结果
</code></pre>

<ul>
<li><strong>xwmn</strong><ul>
<li>功能：获取模块的 <strong>.a</strong> 文件名。</li>
<li>用法举例：</li>
</ul>
</li>
</ul>
<pre><code class="sh">cd ${XWOS_PATH}/xwem/vm/lua # 进入到vm/lua模块中
xwmn
&gt; xwem_vm_lua.a # 输出
</code></pre>

<ul>
<li><strong>xwm</strong><ul>
<li>功能：编译整个玄武OS工程，类似Android的m命令。</li>
<li>用法：xwm [选项] [目标]</li>
<li>选项 -B：全部重新编译一次</li>
<li>目标：make的目标</li>
<li>用法举例：</li>
</ul>
</li>
</ul>
<pre><code class="sh">xwm # 编译整个工程
xwm c # 清理
xwm d # 侧底清理
</code></pre>

<ul>
<li><strong>xwmm</strong><ul>
<li>功能：单独编译模块，类似Android的mm命令，使用当前路径作为模块的路径。</li>
<li>选项 -B：全部重新编译一次</li>
<li>用法举例：</li>
</ul>
</li>
</ul>
<pre><code class="sh">cd ${XWOS_PATH}/xwem/vm/lua # 进入到vm/lua模块中
xwmm
</code></pre>

<ul>
<li><strong>xwmmm</strong><ul>
<li>功能：单独编译模块，类似Android的mmm命令，需要指定模块的路径。</li>
<li>选项 -B：全部重新编译一次</li>
<li>用法举例：</li>
</ul>
</li>
</ul>
<pre><code class="sh">xwmmm xwem/vm/lua
</code></pre>

<ul>
<li>
<p><strong>xwcroot</strong></p>
<ul>
<li>功能：切换到玄武OS的根目录，类似Android的croot命令。</li>
</ul>
</li>
<li>
<p><strong>xwcbd</strong></p>
<ul>
<li>功能：切换到电路板目录。</li>
</ul>
</li>
</ul></div>
            </div>
        </div>

        <footer class="col-md-12">
            <hr>
            <p>Documentation built with <a href="https://www.mkdocs.org/">MkDocs</a>.</p>
        </footer>
        <script>
            var base_url = "../..",
                shortcuts = {"help": 191, "next": 78, "previous": 80, "search": 83};
        </script>
        <script src="../../js/base.js" defer></script>
        <script src="../../search/main.js" defer></script>

        <div class="modal" id="mkdocs_search_modal" tabindex="-1" role="dialog" aria-labelledby="searchModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title" id="searchModalLabel">搜索</h4>
                <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
            </div>
            <div class="modal-body">
                <p>
                    在这里所有文档：
                </p>
                <form>
                    <div class="form-group">
                        <input type="search" class="form-control" placeholder="搜索..." id="mkdocs-search-query" title="Type search term here">
                    </div>
                </form>
                <div id="mkdocs-search-results"></div>
            </div>
            <div class="modal-footer">
            </div>
        </div>
    </div>
</div><div class="modal" id="mkdocs_keyboard_modal" tabindex="-1" role="dialog" aria-labelledby="keyboardModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title" id="keyboardModalLabel">Keyboard Shortcuts</h4>
                <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
            </div>
            <div class="modal-body">
              <table class="table">
                <thead>
                  <tr>
                    <th style="width: 20%;">Keys</th>
                    <th>Action</th>
                  </tr>
                </thead>
                <tbody>
                  <tr>
                    <td class="help shortcut"><kbd>?</kbd></td>
                    <td>Open this help</td>
                  </tr>
                  <tr>
                    <td class="next shortcut"><kbd>n</kbd></td>
                    <td>Next page</td>
                  </tr>
                  <tr>
                    <td class="prev shortcut"><kbd>p</kbd></td>
                    <td>Previous page</td>
                  </tr>
                  <tr>
                    <td class="search shortcut"><kbd>s</kbd></td>
                    <td>Search</td>
                  </tr>
                </tbody>
              </table>
            </div>
            <div class="modal-footer">
            </div>
        </div>
    </div>
</div>

    </body>
</html>
